Repository navigation
perf(agc): mirror a sparse descriptor heap instead of copying it per dispatch - #3167
Conversation
Dextroid17
left a comment
There was a problem hiding this comment.
These two are one line of work on one title, and the second is only safe because of the first — so they want to land in order: #2992 cuts what a copied sparse region costs to its last backed byte, and #3167 removes the per-dispatch copy of a bound heap altogether.
The measurement chain is complete, which is unusual. PPSA28416 binds a 4 GiB GPU heap with 528 MiB committed; before the cut, every dispatch that bound it allocated the whole 4 GiB and failed with vkAllocateMemory … -2; after it, the copy was still 528 MiB per dispatch at ~90 ms, thousands of times during boot, which is the 0.1 FPS the title showed. Stating the intermediate step as well as the final one is what makes the second change's value checkable rather than asserted.
The mirror design is the right answer where a copy is not. Binding a sparse descriptor heap to a persistent mirror of the registered range that actually backs it — looked up for the part that is needed rather than the whole reservation, no part of which any registered range covers — removes the copy instead of shortening it, and committing pages on demand keeps the mirror proportional to what is really used. Refreshing a fully-committed plain mirror from the write watch, the way an address-based build does, is what keeps it honest, and servesView bounding a view start against each mirror's extent is the check that would otherwise be missing.
One thing worth naming in the descriptions: #2992 is currently conflicting, and this change's cut depends on it. So the sequence is a rebase of the first and then this one — and with GuestBufferMemory.hpp touched by both, that order is not optional.
Written with AI assistance.
…dispatch (open PR boykopovar#3167) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Windows run, since the PR has no Intel or Windows results yet: Windows 11, WinLibs GCC 15.2.0 r7, Release, merged onto
Full AI-assisted (Claude Code); I ran this on my machine. |
|
Additional platform validation of standalone PR head Linux: passed — Arch Linux in WSL2 (kernel 6.6.87.2), GCC 16.2.1 20260810; CMake 4.3.1 / Ninja; Release, 1 checks, 0 failures, 0 CTest skips. Built the selected targets and dependencies; this is focused validation, not a full build or full-suite run. Checks: Command after building: This scope checks CPU-side behavior; no GPU execution result is claimed. Internal limitation: heap-mirror subcases returned early because the guest arena was not write-watched in WSL. Zero CTest skips does not include that early return. No title/gameplay validation. These results cover the standalone head, not a merge with current main. |
2a43070 to
38012ec
Compare
|
Rebased onto current Checked on the rebased tree: scoped build + ctest of libSceAgcDriver and neighbours; |
…at backs it (port branch copy of boykopovar#3167)
What
PPSA28416 (STAR WARS: Galactic Racer, UE5) binds a 4 GiB GPU heap of which 528 MiB is committed. With the cut from #2992 the heap is copied only up to its last backed byte, but it is still copied for every dispatch that binds it: 528 MiB at ~90 ms each, over thousands of dispatches during boot, which is the 0.1 FPS the title showed.
A sparse descriptor heap region is now bound to a persistent heap mirror of the registered range that backs it, instead of being copied:
servesViewchecks the view start against the extent of any mirror, so a view past the mirror falls back to the copy.This branch carries the commit of #2992 (rebased, as that PR conflicts with
main); drop it when #2992 merges.Tested
Windows 11, WinLibs GCC 15.2.0, Release, RTX 4080.
agc_driver_graphics(sparseHeapMirrorTestsinBdaResources.cpp): a committed range smaller than the heap descriptor bound over it is mirrored, not copied (sparseBinds+1), the view is cut at the mirror, a GPU store is written back. Without the change it fails witha heap bound whole over a smaller registered range was copied.main).[resources] guest upload ... copieddrops from 4095 MiB (528 MiB really read) to 0.0 MiB per dispatch. Device time per dispatch during boot: 10.7 ms before (9500 dispatches, 101.8 s), 2.6 ms after (3600 dispatches, 9.5 s). The title then stops on garbage indirect dispatch arguments, which is a separate problem.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt.mdfiles or images added to the repository (attach them to this PR)